home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / Ang261Lib.lha / src / main.c < prev    next >
C/C++ Source or Header  |  1994-10-22  |  17KB  |  704 lines

  1. /* UNIX ANGBAND Version 5.0
  2.    main.c: initialization, main() function and main loop
  3.  
  4.    Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
  5.  
  6.    This software may be copied and distributed for educational, research, and
  7.    not for profit purposes provided that this copyright and statement are
  8.    included in all such copies. */
  9.  
  10.  
  11. /* Original copyright message follows. */
  12.  
  13. /* ANGBAND Version 4.8    COPYRIGHT (c) Robert Alan Koeneke        */
  14. /*                                     */
  15. /*     I lovingly dedicate this game to hackers and adventurers     */
  16. /*     everywhere...                             */
  17. /*                                     */
  18. /*                                     */
  19. /*     Designer and Programmer : Robert Alan Koeneke             */
  20. /*                   University of Oklahoma         */
  21. /*                                     */
  22. /*     Assistant Programmers     : Jimmey Wayne Todd             */
  23. /*                   University of Oklahoma         */
  24. /*                                     */
  25. /*                   Gary D. McAdoo             */
  26. /*                   University of Oklahoma         */
  27. /*                                     */
  28. /*     UNIX Port         : James E. Wilson             */
  29. /*                   UC Berkeley                 */
  30. /*                   wilson@ernie.Berkeley.EDU         */
  31. /*                   ucbvax!ucbernie!wilson         */
  32. /*                                     */
  33. /*     MSDOS Port         : Don Kneller                 */
  34. /*                   1349 - 10th ave             */
  35. /*                   San Francisco, CA 94122         */
  36. /*                   kneller@cgl.ucsf.EDU             */
  37. /*                   ...ucbvax!ucsfcgl!kneller         */
  38. /*                   kneller@ucsf-cgl.BITNET         */
  39. /*                                     */
  40. /*     BRUCE ANGBAND         : Christopher Stuart             */
  41. /*                   Monash University             */
  42. /*                   Melbourne, Victoria, AUSTRALIA     */
  43. /*                   cjs@moncsbruce.oz             */
  44. /*                                     */
  45. /*     ANGBAND may be copied and modified freely as long as the above     */
  46. /*     credits are retained.    No one who-so-ever may sell or market     */
  47. /*     this software in any form without the expressed written consent */
  48. /*     of the author Robert Alan Koeneke.                 */
  49. /*                                     */
  50.  
  51. #include <stdio.h>
  52.  
  53. /* include before constant, because param.h defines NULL incorrectly */
  54. #ifndef USG
  55. #include <sys/types.h>
  56. #include <sys/param.h>
  57. #include <sys/time.h>
  58. #include <sys/resource.h>
  59. #endif
  60.  
  61. #include "constant.h"
  62. #include "config.h"
  63. #include "types.h"
  64. #include "externs.h"
  65.  
  66. #ifdef USG
  67. #include <string.h>
  68. #else
  69. #include <strings.h>
  70. #endif
  71.  
  72. #ifdef ultrix
  73. #include <sys/stat.h>
  74. #endif
  75.  
  76. #include <ctype.h>
  77.  
  78. #ifndef ibm032
  79. #include <time.h>
  80. #endif
  81.  
  82. #if defined(ultrix) || defined(USG)
  83. void perror();
  84. #endif
  85.  
  86. #ifdef USG
  87. void exit();
  88. #endif
  89.  
  90. /* Lets do all prototypes correctly.... -CWS */
  91. #ifndef NO_LINT_ARGS
  92. #ifdef __STDC__
  93. static int d_check(char *);
  94. #else
  95. static int d_check();
  96. #endif
  97.  
  98. static void init_m_level();
  99. static void init_t_level();
  100. static void char_inven_init();
  101. #endif
  102.  
  103. #if (COST_ADJ != 100)
  104. static void price_adjust();
  105. #endif
  106. int unfelt    = TRUE;
  107. int be_nasty  = FALSE;
  108. int rating    = 0;
  109. int peek      = FALSE;
  110. int player_uid;
  111. int quests[MAX_QUESTS];
  112. creature_type ghost;
  113.  
  114.  
  115. /* Unique artifact weapon flags, even though some are in the wrong place!*/
  116. int32 GROND, RINGIL, AEGLOS, ARUNRUTH, MORMEGIL, ANGRIST, GURTHANG,
  117.   CALRIS, ANDURIL, STING, ORCRIST, GLAMDRING, DURIN, AULE, THUNDERFIST,
  118.   BLOODSPIKE, DOOMCALLER, NARTHANC, NIMTHANC, DETHANC, GILETTAR, RILIA,
  119.   BELANGIL, BALLI, LOTHARANG, FIRESTAR, ERIRIL, CUBRAGOL, BARD, COLLUIN,
  120.   HOLCOLLETH, TOTILA, PAIN, ELVAGIL, AGLARANG, EORLINGAS, BARUKKHELED,
  121.   WRATH, HARADEKKET, MUNDWINE, GONDRICAM, ZARCUTHRA, CARETH, FORASGIL,
  122.   CRISDURIAN, COLANNON, HITHLOMIR, THALKETTOTH, ARVEDUI, THRANDUIL, THENGEL,
  123.   HAMMERHAND, CELEBORN, THROR, MAEDHROS, OLORIN, ANGUIREL, OROME,
  124.   EONWE, THEODEN, ULMO, OSONDIR, TURMIL, TIL, DEATHWREAKER, AVAVIR, TARATOL;
  125.  
  126. /* Unique artifact armor flags */
  127. int32 DOR_LOMIN, NENYA, NARYA, VILYA, BELEGENNON, FEANOR, ISILDUR, SOULKEEPER,
  128. FINGOLFIN, ANARION, POWER, PHIAL, BELEG, DAL, PAURHACH, PAURNIMMEN, PAURAEGEN,
  129. PAURNEN, CAMMITHRIM, CAMBELEG, INGWE, CARLAMMAS, HOLHENNETH, AEGLIN, CAMLOST,
  130. NIMLOTH, NAR, BERUTHIEL, GORLIM, ELENDIL, THORIN, CELEGORM, THRAIN,
  131. GONDOR, THINGOL, THORONGIL, LUTHIEN, TUOR, ROHAN, TULKAS, NECKLACE, BARAHIR,
  132. CASPANION, RAZORBACK, BLADETURNER;
  133.  
  134. /* Initialize, restore, and get the ball rolling.    -RAK-    */
  135. int
  136. main(argc, argv)
  137. int argc;
  138. char *argv[];
  139. {
  140.     int generate, i;
  141.     int result=FALSE, FIDDLE=FALSE;
  142. #ifndef __MINT__
  143.     FILE *fp;
  144. #endif
  145.     int new_game = FALSE;
  146.     int force_rogue_like = FALSE;
  147.     int force_keys_to = FALSE;
  148. #ifndef __MINT__
  149.     char temphost[MAXHOSTNAMELEN+1], thishost[MAXHOSTNAMELEN+1], discard[120];
  150. #endif
  151.     char string[80];
  152.     struct rlimit rlp;
  153.     
  154. #if !defined(MSDOS) && !defined(HPUX)
  155.     /* Disable core dumps */
  156.     getrlimit(RLIMIT_CORE,&rlp);
  157.     rlp.rlim_cur=0;
  158.     setrlimit(RLIMIT_CORE,&rlp);
  159. #endif
  160.     
  161.     /* default command set defined in config.h file */
  162.     rogue_like_commands = ROGUE_LIKE;
  163.     
  164.     strcpy(py.misc.name, "\0");
  165.     
  166. #ifndef MSDOS
  167. #ifndef SET_UID
  168.     (void) umask(0);
  169. #endif
  170. #endif
  171.     
  172. #ifdef SECURE
  173.     Authenticate();
  174. #endif
  175.     
  176. #ifdef MSDOS            /* -CFT */
  177.     msdos_init();        /* set up some screen stuff + get cnf file */
  178. #endif
  179.     
  180. #ifdef NEW_FILEPATHS
  181.     /* This looks like a good spot to check for our files. - [cjh] */
  182.     get_file_paths();
  183. #endif
  184.     
  185.     /* call this routine to grab a file pointer to the highscore file */
  186.     /* and prepare things to relinquish setuid privileges */
  187.     init_scorefile();
  188.     
  189.     /* Call this routine to grab a file pointer to the log files and
  190.        start the backup process before relinquishing setuid privileges */
  191.     
  192.     init_files();
  193.     
  194. #ifndef MSDOS
  195.     if ((player_uid = getuid()) < 0) {
  196.     perror("Can't set permissions correctly!  Getuid call failed.\n");
  197.     exit(0);
  198.     }
  199.     user_name(py.misc.name, player_uid);
  200. #else
  201.     user_name(py.misc.name);
  202. #endif
  203.     
  204. #if defined(SET_UID) && !defined(SECURE)
  205.     if (setuid(geteuid()) != 0) {
  206.     perror("Can't set permissions correctly!  Setuid call failed.\n");
  207.     exit(0);
  208.     }
  209. #endif
  210.     
  211. #ifdef ANNOY
  212.     if (player_uid == ANNOY)
  213.     be_nasty=TRUE;
  214.     else
  215.     be_nasty=FALSE;
  216. #else
  217.     be_nasty=FALSE;
  218. #endif
  219.     
  220. #if !defined(MSDOS) && !defined(__MINT__)
  221.     (void)gethostname(thishost, (sizeof thishost) - 1);    /* get host */
  222.     if ((fp=my_tfopen(ANGBAND_LOAD, "r")) == NULL) {
  223.     perror("Can't get load-check.\n");
  224.     exit(0);
  225.     }
  226.     
  227.     do {
  228.     if (fscanf(fp, "%s%d", temphost, &LOAD) == EOF) {
  229.         LOAD=100;
  230.         break;
  231.     }
  232.     if (temphost[0]=='#')
  233.         (void)fgets(discard, (sizeof discard)-1, fp); /* Comment */
  234.     } while (strcmp(temphost,thishost) && strcmp(temphost,"localhost"));
  235.     /* Until we've found ourselves */
  236.     
  237.     fclose(fp);
  238. #endif
  239.     
  240.     /* use curses */
  241.     init_curses();
  242.     
  243.     /* check for user interface option */
  244.     for (--argc, ++argv; argc > 0 && argv[0][0] == '-'; --argc, ++argv)
  245.     switch (argv[0][1]) {
  246.       case 'A':
  247.       case 'a':
  248.         if (is_wizard(player_uid))
  249.         peek=TRUE;
  250.         else goto usage;
  251.         break;
  252.       case 'N':
  253.       case 'n': new_game = TRUE; break;
  254.       case 'O':
  255.       case 'o':
  256.         /* rogue_like_commands may be set in get_char(), so delay this
  257.            until after read savefile if any */
  258.         force_rogue_like = TRUE;
  259.         force_keys_to = FALSE;
  260.         break;
  261.       case 'R':
  262.       case 'r':
  263.         force_rogue_like = TRUE;
  264.         force_keys_to = TRUE;
  265.         break;
  266.       case 'S':
  267.       case 's':
  268.         init_curses();
  269.         if (isdigit((int)argv[0][2]))
  270.         display_scores(0, atoi(&argv[0][2]));
  271.         else
  272.         display_scores(0, 10);
  273.         exit_game();
  274.       case 'D':
  275.       case 'd':
  276.         if (!is_wizard(player_uid))
  277.         goto usage;
  278.         if (isdigit((int)argv[0][2]))
  279.         delete_entry(atoi(&argv[0][2]));
  280.         else
  281.         display_scores(0, 10);
  282.         exit_game();
  283.       case 'F':
  284.       case 'f':
  285.         if (is_wizard(player_uid) || to_be_wizard)
  286.         FIDDLE=TRUE;
  287.         else
  288.         goto usage;
  289.         break;
  290.       case 'W':
  291.       case 'w':
  292.         if (is_wizard(player_uid))
  293.         to_be_wizard = TRUE;
  294.         else
  295.         goto usage;
  296. #ifndef MSDOS
  297.         if (isdigit((int)argv[0][2]))
  298.         player_uid = atoi(&argv[0][2]);
  299. #endif
  300.         break;
  301.       case 'u':
  302.       case 'U':
  303.         if (argv[0][2]) {
  304.         strcpy(py.misc.name, &argv[0][2]);
  305.         d_check(py.misc.name);
  306.         NO_SAVE=TRUE;
  307.         } else {
  308.         goto usage;
  309.         }
  310.         break;
  311.       default:
  312.       usage:
  313.         if (is_wizard(player_uid)) {
  314. #ifdef MSDOS
  315.         puts("Usage: angband [-afnorw] [-s<num>] [-d<num>] <file>");
  316. #else
  317.         puts("Usage: angband [-afnor] [-s<num>] [-u<name>] [-w<uid>] [-d<num>]");
  318. #endif
  319.         puts("  a       Activate \"peek\" mode");
  320.         puts("  d<num>  Delete high score number <num>");
  321.         puts("  f       Enter \"fiddle\" mode");
  322.         puts("  n       Start a new character");
  323.         puts("  o       Use original command set");
  324.         puts("  r       Use the \"rogue-like\" command set");
  325.         puts("  s<num>  Show high scores.  Show <num> scores, or first 10");
  326. #ifdef MSDOS
  327.         puts("  w       Start in wizard mode");
  328.         puts(" <file>   Play with savefile named <file>");
  329. #else
  330.         puts("  w<num>  Start in wizard mode, as uid number <num>");
  331.         puts("  u<name> Play with character named <name>");
  332. #endif
  333.         puts("Each option must be listed separately (ie '-r -n', not '-rn')");
  334.         }
  335.         else {
  336. #ifdef MSDOS
  337.         puts("Usage: angband [-nor] [-s<num>] <file>");
  338. #else
  339.         puts("Usage: angband [-nor] [-s<num>] [-u<name>]");
  340. #endif
  341.         puts("  n       Start a new character");
  342.         puts("  o       Use original command set");
  343.         puts("  r       Use the \"rogue-like\" command set");
  344.         puts("  s<num>  Show high scores.  Show <num> scores, or first 10");
  345. #ifdef MSDOS
  346.         puts(" <file>   Play with savefile named <file>");
  347. #else
  348.         puts("  u<name> Play with character named <name>");
  349. #endif
  350.         puts("Each option must be listed separately (ie '-r -n', not '-rn')");
  351.         }
  352.         exit(1);
  353.     }
  354.  
  355.     /* catch those nasty signals */
  356.     /* must come after init_curses as some of the signal handlers use curses */
  357.     init_signals();
  358.  
  359.     /* Check operating hours            */
  360.     /* If not wizard  No_Control_Y            */
  361.     read_times();
  362.  
  363.     /* Some necessary initializations        */
  364.     /* all made into constants or initialized in variables.c */
  365.  
  366. #if (COST_ADJ != 100)
  367.     price_adjust();
  368. #endif
  369.  
  370.     /* Grab a random seed from the clock          */
  371.     init_seeds();
  372.  
  373.     /* Init monster and treasure levels for allocate */
  374.     init_m_level();
  375.     init_t_level();
  376.  
  377.     /* Init the store inventories            */
  378.     store_init();
  379.  
  380. #ifndef MAC
  381.     /* On Mac, if -n is passed, no savefile is used */
  382.     /* If -n is not passed, the calling routine will know savefile name,
  383.        hence, this code is not necessary */
  384. #endif
  385.  
  386.     (void) sprintf(savefile, "%s/%d%s", ANGBAND_SAV, player_uid, py.misc.name);
  387.  
  388.  /* This restoration of a saved character may get ONLY the monster memory. In
  389.     this case, get_char returns false. It may also resurrect a dead character
  390.     (if you are the wizard). In this case, it returns true, but also sets the
  391.     parameter "generate" to true, as it does not recover any cave details. */
  392.  
  393.     if (FIDDLE) {
  394.     if (get_char(&generate))
  395.         save_char();
  396.     exit_game();
  397.     }
  398.  
  399.     result = get_char(&generate);
  400.     /* enter wizard mode before showing the character display, but must wait
  401.        until after get_char in case it was just a resurrection */
  402.     if (to_be_wizard)
  403.     if (!enter_wiz_mode())
  404.         exit_game();
  405.  
  406.     if ((new_game == FALSE) && result) {
  407.     change_name();
  408.  
  409.     /* could be restoring a dead character after a signal or HANGUP */
  410.     if (py.misc.chp < 0)
  411.         death = TRUE;
  412.     } else {            /* Create character */
  413.     /* Unique Weapons, Armour and Rings */
  414.     GROND=0;
  415.     RINGIL=0;
  416.     AEGLOS=0;
  417.     ARUNRUTH=0;
  418.     MORMEGIL=0;
  419.     ANGRIST=0;
  420.     GURTHANG=0;
  421.     CALRIS=0;
  422.     ANDURIL=0;
  423.     STING=0;
  424.     ORCRIST=0;
  425.     GLAMDRING=0;
  426.     DURIN=0;
  427.     AULE=0;
  428.     THUNDERFIST=0;
  429.     BLOODSPIKE=0;
  430.     DOOMCALLER=0;
  431.     NARTHANC=0;
  432.     NIMTHANC=0;
  433.     DETHANC=0;
  434.     GILETTAR=0;
  435.     RILIA=0;
  436.     BELANGIL=0;
  437.     BALLI=0;
  438.     LOTHARANG=0;
  439.     FIRESTAR=0;
  440.     ERIRIL=0;
  441.     CUBRAGOL=0;
  442.     BARD=0;
  443.     COLLUIN=0;
  444.     HOLCOLLETH=0;
  445.     TOTILA=0;
  446.     PAIN=0;
  447.     ELVAGIL=0;
  448.     AGLARANG=0;
  449.     EORLINGAS=0;
  450.     BARUKKHELED=0;
  451.     WRATH=0;
  452.     HARADEKKET=0;
  453.     MUNDWINE=0;
  454.     GONDRICAM=0;
  455.     ZARCUTHRA=0;
  456.     CARETH=0;
  457.     FORASGIL=0;
  458.     CRISDURIAN=0;
  459.     COLANNON=0;
  460.     HITHLOMIR=0;
  461.     THALKETTOTH=0;
  462.     ARVEDUI=0;
  463.     THRANDUIL=0;
  464.     THENGEL=0;
  465.     HAMMERHAND=0;
  466.     CELEGORM=0;
  467.     THROR=0;
  468.     MAEDHROS=0;
  469.     OLORIN=0;
  470.     ANGUIREL=0;
  471.     OROME=0;
  472.     EONWE=0;
  473.     THEODEN=0;
  474.     ULMO=0;
  475.     OSONDIR=0;
  476.     TURMIL=0;
  477.     TIL=0;
  478.     DEATHWREAKER=0;
  479.     AVAVIR=0;
  480.     TARATOL=0;
  481.     DOR_LOMIN=0;
  482.     BELEGENNON=0;
  483.     FEANOR=0;
  484.     ISILDUR=0;
  485.     SOULKEEPER=0;
  486.     FINGOLFIN=0;
  487.     ANARION=0;
  488.     BELEG=0;
  489.     DAL=0;
  490.     PAURHACH=0;
  491.     PAURNIMMEN=0;
  492.     PAURAEGEN=0;
  493.     PAURNEN=0;
  494.     CAMMITHRIM=0;
  495.     CAMBELEG=0;
  496.     HOLHENNETH=0;
  497.     AEGLIN=0;
  498.     CAMLOST=0;
  499.     NIMLOTH=0;
  500.     NAR=0;
  501.     BERUTHIEL=0;
  502.     GORLIM=0;
  503.     THORIN=0;
  504.     CELEBORN=0;
  505.     GONDOR=0;
  506.     THINGOL=0;
  507.     THORONGIL=0;
  508.     LUTHIEN=0;
  509.     TUOR=0;
  510.     ROHAN=0;
  511.     CASPANION=0;
  512.     RAZORBACK=0;
  513.     BLADETURNER=0;
  514.     NARYA=0;
  515.     NENYA=0;
  516.     VILYA=0;
  517.     POWER=0;
  518.     PHIAL=0;
  519.     INGWE=0;
  520.     CARLAMMAS=0;
  521.     TULKAS=0;
  522.     NECKLACE=0;
  523.     BARAHIR=0;
  524.     ELENDIL=0;
  525.     THRAIN=0;
  526.  
  527.     for (i=0; i<MAX_QUESTS; i++) quests[i]=0;
  528.  
  529.     quests[SAURON_QUEST]=99;
  530.  
  531.     /* Unique Monster Flags */
  532.     for (i=0; i<MAX_CREATURES; i++)
  533.         u_list[i].exist=0, u_list[i].dead=0;
  534.     create_character();
  535.  
  536.     /* if we're creating a new character, change the savefile name */
  537.     (void) sprintf(savefile, "%s/%d%s", ANGBAND_SAV, player_uid, py.misc.name);
  538.     char_inven_init();
  539.     py.flags.food = 7500;
  540.     py.flags.food_digested = 2;
  541.         if (class[py.misc.pclass].spell == MAGE)
  542.     {            /* Magic realm   */
  543.         clear_screen();    /* makes spell list easier to read */
  544.         calc_spells(A_INT);
  545.         calc_mana(A_INT);
  546.     }
  547.     else if (class[py.misc.pclass].spell == PRIEST)
  548.     {            /* Clerical realm*/
  549.         calc_spells(A_WIS);
  550.         clear_screen();    /* force out the 'learn prayer' message */
  551.         calc_mana(A_WIS);
  552.     }
  553.         if (!_new_log())
  554.     {
  555.         (void) sprintf(string, "Can't get at log file \"%s\".", ANGBAND_LOG);
  556.         msg_print(string);
  557.         exit_game();
  558.     }
  559.     /* prevent ^c quit from entering score into scoreboard,
  560.        and prevent signal from creating panic save until this point,
  561.        all info needed for save file is now valid */
  562.     character_generated = 1;
  563.     generate = TRUE;
  564.     }
  565.  
  566.     if (force_rogue_like)
  567.     rogue_like_commands = force_keys_to;
  568.  
  569.     magic_init();
  570.  
  571.     /* Begin the game                */
  572.     clear_screen();
  573.     prt_stat_block();
  574.     if (generate)
  575.     generate_cave();
  576.  
  577.     /* Loop till dead, or exit            */
  578.     while(!death)
  579.     {
  580.     dungeon();        /* Dungeon logic */
  581.  
  582. #ifndef MAC
  583.     /* check for eof here, see inkey() in io.c */
  584.     /* eof can occur if the process gets a HANGUP signal */
  585.     if (eof_flag)
  586.     {
  587.         (void) strcpy(died_from, "(end of input: saved)");
  588.         if (!save_char())
  589.         {
  590.         (void) strcpy(died_from, "unexpected eof");
  591.         }
  592.         /* should not reach here, by if we do, this guarantees exit */
  593.         death = TRUE;
  594.     }
  595. #endif
  596.     good_item_flag = FALSE;
  597.     if (!death) generate_cave(); /* New level    */
  598.     }
  599.  
  600.     exit_game();        /* Character gets buried. */
  601.     /* should never reach here, but just in case */
  602.     return (0);
  603. }
  604.  
  605.  
  606. /* Init players with some belongings            -RAK-    */
  607. static void
  608. char_inven_init()
  609. {
  610.     register int i, j;
  611.     inven_type inven_init;
  612.     
  613.     /* this is needed for bash to work right, it can't hurt anyway */
  614.     for (i = 0; i < INVEN_ARRAY_SIZE; i++)
  615.     invcopy(&inventory[i], OBJ_NOTHING);
  616.  
  617.     for (i = 0; i < 5; i++)
  618.     {
  619.     j = player_init[py.misc.pclass][i];
  620.     invcopy(&inven_init, j);
  621.     store_bought(&inven_init);
  622.     if (inven_init.tval == TV_SWORD || inven_init.tval == TV_HAFTED
  623.         || inven_init.tval == TV_BOW)
  624.         inven_init.ident |= ID_SHOW_HITDAM;
  625.     (void) inven_carry(&inven_init);
  626.     }
  627.  
  628.     /* weird place for it, but why not? */
  629.     for (i = 0; i < 64; i++)
  630.     spell_order[i] = 99;
  631. }
  632.  
  633.  
  634. /* Initializes M_LEVEL array for use with PLACE_MONSTER    -RAK-    */
  635. static void
  636. init_m_level()
  637. {
  638.     register int i, k;
  639.  
  640.     for (i = 0; i <= MAX_MONS_LEVEL; i++)
  641.     m_level[i] = 0;
  642.  
  643.     k = MAX_CREATURES - WIN_MON_TOT;
  644.     for (i = 0; i < k; i++)
  645.     m_level[c_list[i].level]++;
  646.  
  647.     for (i = 1; i <= MAX_MONS_LEVEL; i++)
  648.     m_level[i] += m_level[i-1];
  649. }
  650.  
  651.  
  652. /* Initializes T_LEVEL array for use with PLACE_OBJECT    -RAK-    */
  653. static void
  654. init_t_level()
  655. {
  656.     register int i, l;
  657.     int tmp[MAX_OBJ_LEVEL+1];
  658.  
  659.     for (i = 0; i <= MAX_OBJ_LEVEL; i++)
  660.     t_level[i] = 0;
  661.     for (i = 0; i < MAX_DUNGEON_OBJ; i++)
  662.     t_level[object_list[i].level]++;
  663.     for (i = 1; i <= MAX_OBJ_LEVEL; i++)
  664.     t_level[i] += t_level[i-1];
  665.  
  666.     /* now produce an array with object indexes sorted by level, by using
  667.        the info in t_level, this is an O(n) sort! */
  668.     /* this is not a stable sort, but that does not matter */
  669.     for (i = 0; i <= MAX_OBJ_LEVEL; i++)
  670.     tmp[i] = 1;
  671.     for (i = 0; i < MAX_DUNGEON_OBJ; i++)
  672.     {
  673.     l = object_list[i].level;
  674.     sorted_objects[t_level[l] - tmp[l]] = i;
  675.     tmp[l]++;
  676.     }
  677. }
  678.  
  679.  
  680. #if (COST_ADJ != 100)
  681. /* Adjust prices of objects                -RAK-    */
  682. static void
  683. price_adjust()
  684. {
  685.     register int i;
  686.  
  687.     /* round half-way cases up */
  688.     for (i = 0; i < MAX_OBJECTS; i++)
  689.     object_list[i].cost = ((object_list[i].cost * COST_ADJ) + 50) / 100;
  690. }
  691. #endif
  692.  
  693. static int
  694. d_check(a)
  695. char *a;
  696. {
  697.     while (*a)
  698.     if (iscntrl(*a)) {
  699.         msg_print("Yuch! No control characters, Thankyou!");
  700.         exit_game();
  701.     } else a++;
  702.     return (0);
  703. }
  704.